package cn.tedu.mall.product.redis.repo;

import java.io.Serializable;
import java.util.List;

/**
 * 访问Redis数据的公共接口
 *
 * @param <T> 存入到Redis中的数据类型
 */
public interface IRedisRepository<T extends Serializable> {

    /**
     * 保存数据到Redis
     * <p>
     * 此数据将被序列化为JSON格式的字符串保存到Redis中
     * <p>
     * 将根据此数据的id生成Redis中的Key，如数据无id将出现错误
     * <p>
     * 此方法既是增加数据的方法，也是修改数据的方法，当此数据id对应的数据在Redis中已存在时，会覆盖原数据
     *
     * @param data 将保存到Redis中的对象
     */
    void setValue(T data);

    /**
     * 保存空字符串数据到Redis
     * <p>
     * 此方法主要用于解决缓存穿透问题，避免无效id的访问反复冲击数据库
     * <p>
     * 请注意：空数据应有过期时间，具体过期时间取决于具体实现
     *
     * @param id 数据id
     * @see cn.tedu.mall.product.redis.constant.RedisConst#EMPTY_VALUE
     */
    void setEmptyValue(Long id);

    /**
     * 设置最近加载（全部）缓存时间，用于避免频繁重建缓存
     */
    void setRecentlyLoadTime();

    /**
     * 保存数据到Redis的列表中
     * <p>
     * 如Redis中无列表，将创建空列表，并将此数据插入到列表
     *
     * @param item 插入到列表中的数据
     */
    void appendList(T item);

    /**
     * 保存列表数据到Redis的列表中
     * <p>
     * 如Redis中无列表，将创建空列表，并将此列表数据插入
     *
     * @param list 插入到列表中的数据
     */
    void appendList(List<T> list);

    /**
     * 删除Redis中的数据
     *
     * @param id 数据id
     * @return 删除是否成功
     */
    Boolean deleteValue(Long id);

    /**
     * 删除Redis中的列表（仅针对当前类型的数据）
     *
     * @return 删除是否成功
     */
    Boolean deleteList();

    /**
     * 清空Redis（仅针对当前类型的数据）
     */
    void flushAll();

    /**
     * 获取最近加载（全部）缓存时间
     *
     * @return 最近加载缓存时间
     */
    Long getRecentlyLoadTime();

    /**
     * 根据数据id从Redis中获取数据
     *
     * @param id 数据id
     * @return 此id在Redis中匹配的数据，如无匹配的数据，则返回null，需注意，如果此id对应的数据是空数据，则返回空数据，所以，通过此方法获取数据时，可能需要判断是否为空数据
     * @see cn.tedu.mall.product.redis.constant.RedisConst#EMPTY_VALUE
     */
    Serializable getValue(Long id);

    /**
     * 获取列表数据的长度
     *
     * @return 列表数据的长度
     */
    Long listSize();

    /**
     * 从Redis中获取列表（仅针对当前类型的数据）
     *
     * @return 列表数据
     */
    List<T> list();

    /**
     * 从Redis中获取列表（仅针对当前类型的数据）
     *
     * @param page     页码
     * @param pageSize 每页记录数
     * @return 列表数据
     */
    List<T> list(Integer page, Integer pageSize);

}
